﻿Imports System.Collections

Namespace DoFactory.GangOfFour.Flyweight.Structural


    ''' <summary>
    ''' MainApp startup class for Structural
    ''' Flyweight Design Pattern.
    ''' </summary>
    Public Class MainApp
        ''' <summary>
        ''' Entry point into console application.
        ''' </summary>
        Public Shared Sub Main()

            ' Arbitrary extrinsic state
            Dim extrinsicstate As Integer = 22
            Dim factory As New FlyweightFactory()

            ' Work with different flyweight instances
            Dim fx As Flyweight = factory.GetFlyweight("X")
            fx.Operation(System.Threading.Interlocked.Decrement(extrinsicstate))

            Dim fy As Flyweight = factory.GetFlyweight("Y")
            fy.Operation(System.Threading.Interlocked.Decrement(extrinsicstate))

            Dim fz As Flyweight = factory.GetFlyweight("Z")
            fz.Operation(System.Threading.Interlocked.Decrement(extrinsicstate))

            Dim fu As New UnsharedConcreteFlyweight()
            fu.Operation(System.Threading.Interlocked.Decrement(extrinsicstate))

        End Sub

    End Class

    ''' <summary>
    ''' The 'FlyweightFactory' class
    ''' </summary>
    Class FlyweightFactory

        Private flyweights As New Hashtable()

        ' Constructor
        Public Sub New()
            flyweights.Add("X", New ConcreteFlyweight())

            flyweights.Add("Y", New ConcreteFlyweight())

            flyweights.Add("Z", New ConcreteFlyweight())
        End Sub

        Public Function GetFlyweight(ByVal key As String) As Flyweight
            Return DirectCast(flyweights(key), Flyweight)
        End Function

    End Class

    ''' <summary>
    ''' The 'Flyweight' abstract class
    ''' </summary>
    MustInherit Class Flyweight

        Public MustOverride Sub Operation(ByVal extrinsicstate As Integer)

    End Class

    ''' <summary>
    ''' The 'ConcreteFlyweight' class
    ''' </summary>
    Class ConcreteFlyweight
        Inherits Flyweight

        Public Overrides Sub Operation(ByVal extrinsicstate As Integer)
            Console.WriteLine("ConcreteFlyweight: " & extrinsicstate)
        End Sub

    End Class

    ''' <summary>
    ''' The 'UnsharedConcreteFlyweight' class
    ''' </summary>
    Class UnsharedConcreteFlyweight
        Inherits Flyweight

        Public Overrides Sub Operation(ByVal extrinsicstate As Integer)
            Console.WriteLine("UnsharedConcreteFlyweight: " & extrinsicstate)
        End Sub

    End Class

End Namespace
